package com.amkai.aes.webservice.binary.objecthandler.registration;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amkai.aes.aescommon.service.binary.job.registration.FreeAppointmentsJob;
import com.amkai.aes.generatedbeans.organization.Department;
import com.amkai.aes.generatedbeans.organization.DepartmentKind;
import com.amkai.aes.generatedbeans.pmcase.PmCase;
import com.amkai.aes.generatedbeans.reference.PersonReference;
import com.amkai.aes.generatedbeans.registration.Patient;
import com.amkai.aes.generatedbeans.scheduling.AbstractAppointment;
import com.amkai.aes.generatedbeans.scheduling.AppointmentStatusInfo;
import com.amkai.aes.generatedbeans.scheduling.ResourceConnection;
import com.amkai.aes.webservice.binary.JobObjectHandler;
import com.amkai.common.extensions.hibernate.config.SiteManager;
import com.amkai.common.extensions.hibernate.config.manager.SessionManager;

public class FreeAppointmentHandler implements JobObjectHandler<FreeAppointmentsJob, Serializable, AbstractAppointment[]> {
	
	private static final Log logger = LogFactory.getLog(FreeAppointmentHandler.class);
	
	@Override
	public AbstractAppointment[] process(FreeAppointmentsJob job, Serializable object) throws Exception {
		SessionManager sm = SiteManager.Start();
		sm.openSession();
		
		AbstractAppointment[] result = null;
		
		try {
			Long personId = job.getPersonId();
			Long appToFree = job.getAppointmentToFree();
			
			Department dep = sm.get(Department.class, job.getModuleDepartment().getId());
			
			String className = "AbstractAppointment";
			
//			if (dep.getDepartmentType().getKind() == DepartmentKind.PRACTICE_MANAGEMENT) {
//				className = "PracticeManagementAppointment";
//			}
//			else if (dep.getDepartmentType().getKind() == DepartmentKind.SURGERY_CENTER) {
//				className = "SurgeryCenterAppointment";
//			}
			
			//FREE AN APPOINTMENT
			if (appToFree != null) {
				AbstractAppointment aa = sm.get(AbstractAppointment.class, appToFree);
				
				PmCase pmCase = aa.getPmCase();
				
				AbstractAppointment aaToRemove = null;
				for(AbstractAppointment tmpAa : pmCase.getAbstractAppointments()) {
					if (tmpAa.getId().equals(aa.getId())) {
						aaToRemove = tmpAa;
					}
				}
				
				pmCase.getAbstractAppointments().remove(aaToRemove);
				aaToRemove.setPmCase(null);
				sm.saveRAD(pmCase);
				sm.saveRAD(aaToRemove);
				
			}
			//GET APPOINTMENT LIST
			else {

				List appointments = sm.execute("FROM "+ className +" aa " +
									  "left join fetch aa.resourceConnections as rescon "+
									  "left join fetch rescon.reservation as res "+
									  "left join fetch res.schedulingResource as sr "+
									  "left join fetch sr.reference as ref " +
									  "where exists(FROM PersonReference persref WHERE persref.id = ref.id AND persref.person = :persid) AND " +
									  "		aa.department = :depid AND " +
									  "     aa.pmCase IS NULL AND " +
									  "		exists (FROM AppointmentStatusInfo asi WHERE asi.abstractScheduleIssue.id = aa.id " +
									  "			AND asi.changeDate = (SELECT max(changeDate) FROM AppointmentStatusInfo aai WHERE aai.abstractScheduleIssue.id = aa.id)) " +
	//								  "			AND asi.statusKindWrapper NOT IN ("+ AppointmentStatusKind.CANCELED.ordinal() +", "+ AppointmentStatusKind.NO_SHOW.ordinal() +")) " +
									  " ORDER BY aa.beginTime")
									  .setLong("persid", job.getPersonId()).setLong("depid", job.getModuleDepartment().getId()).list();
				
				result = new AbstractAppointment[appointments.size()];
				int i=0;
				for(Object o: appointments) {
					
					AbstractAppointment aa = (AbstractAppointment)o;
					
					aa.getAppointmentType().getName();
					
					for(AppointmentStatusInfo asi : aa.getAppointmentStatusInfoes()) {
						asi.getChangeDate();
					}
					
					for(ResourceConnection resc : aa.getResourceConnections()) {
						if (resc.getReservation() != null) { 
							resc.getReservation().getBeginTime();
							if (resc.getReservation().getSchedulingResource() != null && 
								resc.getReservation().getSchedulingResource().getReference() != null && 
								resc.getReservation().getSchedulingResource().getReference() instanceof PersonReference) {
								
								((PersonReference)resc.getReservation().getSchedulingResource().getReference()).getPerson().getLastName();
							}
						}
					}
					
					result[i] = aa;
					i++;
				}
			}
			
			sm.closeSession();
			
		} catch( Exception exception) {
			
			exception.printStackTrace();
			logger.error("FreeAppointmentHandler: ", exception);
			throw exception;
			
		} finally {
			sm.closeSession();
		}
		return result;
	}

}
